#include "getattentionstask.h"
#include "libs/base/service/downloader.h"
#include "libs/core/model/attentionmodel.h"
#include "libs/core/model/model.h"
#include "libs/core/model/presentermodel.h"
#include "services/yingceservice.h"
#include "usersettings.h"
#include "yingce.h"
#include <QUrl>

GetAttentionsTask::GetAttentionsTask(QObject* parent) : yc::Task { 0, true, 0, parent } { }

void GetAttentionsTask::startImpl()
{
    getAttentions(0);
}

void GetAttentionsTask::getAttentions(int page_num)
{
    YingCeService::instance()->getAttentions(
            page_num,
            yc::ResponseHandler(
                    this,
                    [this, page_num](const yc::Request& request, const yc::Response& response) {
                        Q_UNUSED(request)
                        if (response.status() == yc::OK_CODE) {
                            const auto jo = response.data().toObject();
                            int count = jo["totalCount"].toInt();
                            const auto ja = jo["attentions"].toArray();
                            for (const auto& i : ja) {
                                yc::Attention a { i.toObject() };
                                attentions_.push_back(a);
                            }

                            if (attentions_.size() < count) {
                                getAttentions(page_num + 1);
                            } else {
                                pos_ = 0;
                                getPresenters();
                            }
                        } else {
                            Q_EMIT failed(yc::SERVICE_ERROR, response.msg());
                        }
                    }));
}

void GetAttentionsTask::getPresenters()
{
    int count = attentions_.size();
    if (pos_ >= count) {
        downloadAvatars();
    } else {
        QList<int> ids = { 0 };
        int last = pos_ + 50;
        if (last >= count) {
            last = count;
        }
        for (int i = pos_; i < last; ++i) {
            ids.push_back(attentions_.at(i).presenter);
        }
        pos_ = last;
        YingCeService::instance()->getPresenters(
                ids,
                yc::ResponseHandler(
                        this, [this](const yc::Request& request, const yc::Response& response) {
                            Q_UNUSED(request)
                            if (response.status() == yc::OK_CODE) {
                                auto pm = YingCe::instance()->model()->presenterModel();
                                const auto ja = response.data().toArray();
                                for (const auto& i : ja) {
                                    const yc::Presenter pr { i.toObject() };
                                    pm->add(pr);
                                }
                                // next
                                getPresenters();
                            } else {
                                Q_EMIT failed(yc::SERVICE_ERROR, response.msg());
                            }
                        }));
    }
}

void GetAttentionsTask::downloadAvatars()
{
    QList<yc::DownloadResource> resources;
    const auto res_dir = UserSettings::instance().resDir();
    auto pm = YingCe::instance()->model()->presenterModel();
    for (const auto p : pm->presenters()) {
        if (!p->avatar.isEmpty()) {
            const auto filename = QUrl { p->avatar }.fileName();
            if (!QFileInfo::exists(res_dir.absoluteFilePath(filename))) {
                resources.push_back(yc::DownloadResource { p->avatar, filename });
            }
        }
    }
    if (resources.empty()) {
        addAttentions();
    } else {
        downloader_ = new yc::Downloader(YingCeService::instance(), QString(), resources,
                                         UserSettings::instance().resDir(), this);
        connect(downloader_, &yc::Downloader::finished, this, &GetAttentionsTask::addAttentions);
        connect(downloader_, &yc::Downloader::failed, this, &GetAttentionsTask::addAttentions);
        downloader_->start();
    }
}

void GetAttentionsTask::addAttentions()
{
    auto am = YingCe::instance()->model()->attentionModel();
    for (const auto& i : std::as_const(attentions_)) {
        am->add(i);
    }
    Q_EMIT finished();
}
